<?php
class Answer_Service_Category extends Phpfox_Service
{
    function __construct()
    {
        $this->_sTable = Phpfox::getT('brodev_answer_category');
    }

    /**
     * get all child id
     * @param $iId
     * @return string
     */
    public function getAllId($iId)
    {
        $sResult = $iId;
        $aCategories = $this->database()
            ->select('c.id')
            ->from($this->_sTable, 'c')
            ->where('c.parent_id =' . $iId)
            ->order('c.name')
            ->execute('getRows');

        foreach ($aCategories AS $Category) {
            $sResult .= "," . $Category['id'];
        }

        return $sResult;
    }

    /**
     * get categories from database with page
     * @param string $sFields
     * @param array $aCondition
     * @param int $iPage
     * @param int $iLimit
     * @return array
     */
    public function getList($sFields = '*', $aCondition, $iPage, $iLimit = 20)
    {
        $iCount = $this->database()
            ->select('COUNT(*)')
            ->from($this->_sTable, 'c')
            ->where($this->getCondition($aCondition))
            ->execute('getField');
        $aCategories = $this->database()
            ->select($sFields . ', pc.name as parent_name')
            ->from($this->_sTable, 'c')
            ->where($this->getCondition($aCondition))
            ->leftJoin($this->_sTable, 'pc', 'c.parent_id = pc.id')
            ->limit($iPage, $iLimit, $iCount)
            ->order('c.name')
            ->execute('getRows');
        return array(
            'data' => $aCategories,
            'count' => $iCount
        );
    }

    /**
     * get categories from database without page
     * @param string $sFields
     * @param array $aConditions
     * @return array
     */
    public function getListNoPage($sFields = 'c.*', $aConditions = array())    {

        $aCategories = $this->database()
                ->select($sFields . ', pc.name as parent_name')
                ->from($this->_sTable, 'c')
                ->where($this->getCondition($aConditions))
                ->leftJoin($this->_sTable, 'pc', 'c.parent_id = pc.id')
                ->order('c.ordering')
                ->execute('getRows');
        return array(
            'data' => $aCategories
        );
    }

    /**
     * convert array to condition string
     * @param array $aCondition
     * @return string
     *
     */
    private function getCondition($aCondition)
    {
        $sCondition = "1=1";
        foreach ($aCondition AS $Array) {
            $sCondition .= " AND " . $Array;
        }
        return $sCondition;
    }

    /**
     * Get Parent ID
     * @param $iId
     * @return int
     */
    public function getParentId($iId)
    {
        $iParentId = $aRecords = $this->database()
            ->select('parent_id')
            ->from($this->_sTable)
            ->where('id = ' . $iId)
            ->execute('getField');
        return $iParentId;
    }

    /**
     * get 1 category from database with condition
     * @param array $aCondition
     * @return array
     */
    public function getForEdit($aCondition)
    {
        $aCategory = $this->database()
            ->select('*')
            ->from($this->_sTable)
            ->where($this->getCondition($aCondition))
            ->execute('getRow');
        return array(
            'data' => $aCategory
        );
    }

    public function getForBrowse($iCategory = 0) {
        $sCacheId = $this->cache()->set('answer_category_'. $iCategory);
        if (!$aCategories =  $this->cache()->get($sCacheId)) {
            $aCategories = $this->database()
                ->select('*')
                ->from($this->_sTable)
                ->where('parent_id = '. $iCategory)
                ->order('ordering')
                ->execute('getRows');

            if (empty($aCategories)) {
                $iParentId = $this->database()
                    ->select('parent_id')
                    ->from($this->_sTable)
                    ->where('id = ' . $iCategory)
                    ->execute('getField');

                if (!$iParentId) {
                    return array();
                }

                $aCategories = $this->database()
                    ->select('*')
                    ->from($this->_sTable)
                    ->where('parent_id = '. $iParentId)
                    ->order('ordering')
                    ->execute('getRows');
            }
                foreach ($aCategories as $iKey => $aCategory) {
                    $aSubCategories = $this->database()
                        ->select('c.*, count(q.id) as total')
                        ->from($this->_sTable, 'c')
                        ->leftJoin(Phpfox::getT('brodev_answer_question'), 'q', 'q.category_id = c.id')
                        ->where('c.parent_id = '. $aCategory['id'])
                        ->order('c.ordering')
                        ->group('c.id')
                        ->execute('getRows');
                    if (!empty($aSubCategories)) {
                        $aCategories[$iKey]['child'] = $aSubCategories;
                    }
                    $aCategories[$iKey]['total'] = Phpfox::getService('answer.question')->countQuestion($aCategory['id']);
                }
            $this->cache()->save($sCacheId, $aCategories);
        }

        return $aCategories;
    }
    /**
     * insert or update category to database
     * @param $aVals
     * @param $iId
     * @return bool
     */
    public function saveDatabase($aVals)
    {
        $iId = $aVals['id'];
        $aCondition = array('id = ' . (int)$iId);
        $this->cache()->remove('answer_category', 'substr');
        if (!$this->isExist($aCondition)) {
            $iId = $this->database()
                ->insert($this->_sTable, $aVals);
            if (!$iId) {
                return false;
            } else {

                return true;
            }
        } else {
            return $this->database()->update($this->_sTable, $aVals, "id = " . $iId);
        }
    }

    /**
     * delete category from database      *
     * @param $iId
     * @return bool
     */
    public function delete($iId)
    {
        $aCondition = array('category_id = ' . $iId);
        $aRecords = Phpfox::getService('answer.question')->getListNoPage('q.*', $aCondition);
        $aRecords = $aRecords['data'];
        foreach ($aRecords as $aItem) {
            Phpfox::getService('answer.question')->delete($aItem['id']);
        }
        $aConditions = array('c.parent_id = ' . $iId);
        $aCategories = Phpfox::getService('answer.category')->getListNoPage('c.id', $aConditions);
        $aCategories = $aCategories['data'];

        foreach ($aCategories AS $aItem) {
            Phpfox::getService('answer.category')->delete($aItem['id']);
        }
        $this->cache()->remove('answer_category', 'substr');
        return $this->database()->delete($this->_sTable, 'id = ' . $iId);
    }

    /**
     * delete all categories
     * @return mixed
     */
    public function deleteAll() {
        $this->cache()->remove('answer_category', 'substr');
         return $this->database()->delete($this->_sTable,'1 = 1');
     }
    /**
     * Check Exist
     * @param array $aCondition
     * @return bool
     */
    public function isExist($aCondition)
    {
        $iCount = $this->database()
            ->select('count(*)')
            ->from($this->_sTable)
            ->where($this->getCondition($aCondition))
            ->execute('getField');
        if ($iCount > 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * @param $aVals
     * @return bool
     */
    public function updateOrder($aVals)
    {
        foreach ($aVals as $iId => $iOrder)
        {
            $this->database()->update($this->_sTable, array('ordering' => $iOrder), 'id = ' . (int) $iId);
        }
        $this->cache()->remove('answer_category', 'substr');
        return true;
    }
    /**
     * get category in admincp
     * @return string
     */
    public function get() {
        $sCacheId = $this->cache()->set('answer_category_all');
        if (!$sOutput = $this->cache()->get($sCacheId)) {
            $sOutput = $this->_get(0);
            $this->cache()->save($sCacheId, $sOutput);
        }
        return $sOutput;
    }
    /**
     * show category in admincp
     * @param $iCategoryId
     * @return string
     */
    private function _get($iCategoryId) {
        $aCategories = $this->database()
            ->select('*')
            ->from($this->_sTable)
            ->where('parent_id = '. (int)$iCategoryId)
            ->order('ordering')
            ->execute('getRows');
        if (count($aCategories))
        {
            $sOutput = "<ul>";
            foreach ($aCategories as $iKey => $aCategory)
            {
                $sOutput .= '<li><img src="' . Phpfox::getLib('template')->getStyle('image', 'misc/draggable.png') . '" alt="" /> <input type="hidden" name="order[' . $aCategory['id'] . ']" value="' . $aCategory['ordering'] . '" class="js_mp_order" /><a href="#?id=' . $aCategory['id'] . '" class="js_drop_down">' . Phpfox::getLib('locale')->convert($aCategory['name']) . '</a>' . $this->_get($aCategory['id']) . '</li>' . "\n";
            }
            $sOutput .= "</ul>";
            return $sOutput;
        }
    }
}